{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 目的：探索三种方式定义的变量之间的区别: tf.placeholder, tf.Variable, tf.get_variable\n",
    "\n",
    "### 重启服务后，运行多次，注意每次运行后打印的结果的不同"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Placeholder:0\n",
      "ph:0\n",
      "ph_1:0\n",
      "<class 'tensorflow.python.framework.ops.Tensor'>\n",
      "Tensor(\"ph_1:0\", shape=(2, 3, 4), dtype=float32)\n",
      "********************\n",
      "Variable:0\n",
      "V:0\n",
      "V_1:0\n",
      "<class 'tensorflow.python.ops.variables.Variable'>\n",
      "<tf.Variable 'V_1:0' shape=(2,) dtype=float32_ref>\n",
      "********************\n",
      "gv:0\n",
      "<class 'tensorflow.python.ops.variables.Variable'>\n",
      "<tf.Variable 'gv:0' shape=(2, 3) dtype=float32_ref>\n"
     ]
    }
   ],
   "source": [
    "import tensorflow as tf\n",
    "# 设置GPU按需增长\n",
    "config = tf.ConfigProto()\n",
    "config.gpu_options.allow_growth = True\n",
    "sess = tf.Session(config=config)\n",
    "\n",
    "# 1.placeholder \n",
    "v1 = tf.placeholder(tf.float32, shape=[2,3,4])\n",
    "print(v1.name)\n",
    "v1 = tf.placeholder(tf.float32, shape=[2,3,4], name='ph')\n",
    "print(v1.name)\n",
    "v1 = tf.placeholder(tf.float32, shape=[2,3,4], name='ph')\n",
    "print(v1.name)\n",
    "print(type(v1))\n",
    "print(v1)\n",
    "\n",
    "print(\"*\"*20)\n",
    "\n",
    "# 2. tf.Variable()\n",
    "v2 = tf.Variable([1,2], dtype=tf.float32)\n",
    "print(v2.name)\n",
    "v2 = tf.Variable([1,2], dtype=tf.float32, name='V')\n",
    "print(v2.name)\n",
    "v2 = tf.Variable([1,2], dtype=tf.float32, name='V')\n",
    "print(v2.name)\n",
    "print(type(v2))\n",
    "print(v2)\n",
    "\n",
    "print(\"*\"*20)\n",
    "\n",
    "# 3.tf.get_variable() 创建变量的时候必须要提供 name\n",
    "v3 = tf.get_variable(name='gv', shape=[])  \n",
    "print(v3.name)\n",
    "# v4 = tf.get_variable(name='gv', shape=[2])\n",
    "# print(v4.name)\n",
    "print(type(v3))\n",
    "print(v3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4\n",
      "<tf.Variable 'Variable:0' shape=(2,) dtype=float32_ref>\n",
      "<tf.Variable 'V:0' shape=(2,) dtype=float32_ref>\n",
      "<tf.Variable 'V_1:0' shape=(2,) dtype=float32_ref>\n",
      "<tf.Variable 'gv:0' shape=(2, 3) dtype=float32_ref>\n"
     ]
    }
   ],
   "source": [
    "# tf.trainable_variables(), 它能够将我们定义的所有的 trainable=True 的所有变量以一个list的形式返回\n",
    "vs = tf.trainable_variables()\n",
    "print(len(vs))\n",
    "for v in vs:\n",
    "    print(v)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "从上面的实验结果来看，这三种方式所定义的变量具有相同的类型。而且只有 tf.get_variable() 创建的变量之间会发生命名冲突。在实际使用中，三种创建变量方式的用途也是分工非常明确的。其中\n",
    "\n",
    "- tf.placeholder() 占位符。* trainable==False *\n",
    "- tf.Variable() 一般变量用这种方式定义。 * 可以选择 trainable 类型 *\n",
    "- tf.get_variable() 一般都是和 tf.variable_scope() 配合使用，从而实现变量共享的功能。* trainable == True*"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda root]",
   "language": "python",
   "name": "conda-root-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
